package Proyecto;

import java.awt.*;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.*;
import javax.swing.*;


public class ProyectoCanvas extends Canvas implements Runnable{

    
    int alto,ancho,altoFila,anchoFila;
    Image muro,carA,carB,carC,carD,carE,carF,carG;
    String mat[][];
    int [][]posicionesCanvas=new int[7][2];
    int [][]posiciones=new int[7][2];
    String []carros={"A","B","C","D","E","F","G"};
    ArrayList<String> vehiculos=new ArrayList<String>(7);
    Thread movimiento=new Thread(this);
    boolean pintados=false;
    boolean animar=false;
    int cont;
    String []parametros;
    Image imgBuff;
    Graphics grafBuff;
    ArrayList<String[]> resultado;
    
    
    public ProyectoCanvas(String matriz[][]){
        this.mat=matriz;
        setBackground(Color.white);
        for (int i = 0; i < 7; i++) {
            vehiculos.add(i,carros[i]);
        }
        cargarImagenes();
    }
    
    
    @Override
    public void update(Graphics g){

        Dimension d= getSize();
        ancho = d.width;
        alto = d.height;
        altoFila = alto/7;
        anchoFila = ancho/7;
        if(grafBuff==null){
            imgBuff = createImage(ancho,alto);
            grafBuff = imgBuff.getGraphics();
        }
        grafBuff.setColor(getBackground());
        grafBuff.fillRect(0, 0, ancho, alto);
        pintarMapa(grafBuff);
        if(!pintados){
            determinarPosicionesIniciales();
            pintados=true;
        }
        for (int i = 0; i < 7; i++) {
            pintarVehiculo(grafBuff,carros[i],posicionesCanvas[i][0],posicionesCanvas[i][1]);
        }
        g.drawImage(imgBuff, 0, 0, this);
    }
    
    
    @Override
    public void paint(Graphics g){
        update(g);
    }
    
    /**
     * Calcula la alineacion del vehiculo: Horizontal o Vertical.
     * @param simbolo Ingresa el simbolo del vehiculo, puede ser A,B,C,D,E,F o G.
     * @return Alineacion del vehiculo.
     */
    public String alineacionVehiculo(String simbolo){
        int al=10;
        String alineacion="Vertical";
        for(int i=0;i<7;i++){
            for(int j=0; j<7; j++){
                if(mat[i][j].equals(simbolo)){
                   if(al==i){
                       alineacion="Horizontal";
                   }
                   al=i;
                }
            }
        }
        return alineacion;
    }
    
    /**
     * Determina el tipo de vehiculo
     * @param simbolo Ingresa el simbolo del vehiculo, puede ser A,B,C,D,E,F o G. 
     * @return 2 si el simbolo representa un carro.
     * @return 3 si el simbolo representa un bus.
     */
    public int tipoVehiculo(String simbolo){
        int contador = 0;
        for(int i=0;i<7;i++){
            for(int j=0; j<7; j++){
                if(mat[i][j].equals(simbolo)){
                   contador++;
                }
            }
        }
        return contador;
    }
    
    /**
     * Asigna la imagen correspondiente al simbolo dependiendo de su alineacion y tipo.
     * @param simbolo Ingresa el simbolo del vehiculo, puede ser A,B,C,D,E,F o G.
     * @return Ruta a la imagen.
     */
    public String imagenTipoVehiculo(String simbolo){
        
        String resultado = "imagenes/";
        if(tipoVehiculo(simbolo)==2){
            resultado = resultado+"Carro"+simbolo+"-"+alineacionVehiculo(simbolo)+".png";
        }else if(tipoVehiculo(simbolo)==3){
            resultado = resultado+"Bus"+"-"+alineacionVehiculo(simbolo)+".png";
        }
        return resultado;
    }
    
    public void pintarVehiculo(Graphics g,String simbolo,int x,int y){
    
        Image imagen = determinarImagen(simbolo);
        if(alineacionVehiculo(simbolo).equals("Vertical")){
            g.drawImage(imagen,x,y,anchoFila,(altoFila)*tipoVehiculo(simbolo),this);
        }else if(alineacionVehiculo(simbolo).equals("Horizontal")){
            g.drawImage(imagen,x,y,(anchoFila)*tipoVehiculo(simbolo),altoFila,this);
        }
    }
    
    public void pintarMapa(Graphics g){
        for(int i=0;i<7;i++){
            g.setColor(Color.black);
            g.drawLine(0, i*altoFila, ancho, i*altoFila);
            for(int j=0;j<7;j++){
                g.setColor(Color.black);
                g.drawLine(j*anchoFila, 0,j*anchoFila, alto);
                if(mat[i][j].equals("1")){
                    g.drawImage(muro,(ancho-3)-(7-j)*anchoFila,(alto-3)-(7-i)*altoFila,anchoFila,altoFila,this);
                   }
                if(mat[i][j].equals("0")){
                   g.setColor(Color.white);
                   g.fillRect((ancho)-(7-j)*anchoFila,(alto)-(7-i)*altoFila,anchoFila,altoFila);
                }
                   }
            }
        }
    
    
    public void determinarPosicionesIniciales(){
        for (int p = 0; p < 7; p++) {
       
        cont=0;
        for(int i=0;i<7;i++){
            for(int j=0;j<7;j++){
                if((mat[i][j].equals(carros[p]))&&cont==0){
                    posiciones[p][0] = j;
                    posiciones[p][1] = i;
                    posicionesCanvas[p][0] = (ancho-3)-(7-j)*anchoFila;
                    posicionesCanvas[p][1] = (alto-3)-(7-i)*altoFila;
                    cont++;
                }
            }
        }
        }
    }
    
    public  void animarSolucion(ArrayList<String[]> resultado){
        resultado.add(new String[]{"A","Derecha","7"});
        this.resultado=resultado;
        movimiento=new Thread(this);
        movimiento.start();
    }
    
    
    public Image determinarImagen(String simbolo){
        Image imagen = null;
        if(simbolo.equals("A")){imagen=carA;}else
            if(simbolo.equals("B")){imagen=carB;}else
                if(simbolo.equals("C")){imagen=carC;}else
                    if(simbolo.equals("D")){imagen=carD;}else
                        if(simbolo.equals("E")){imagen=carE;}else
                            if(simbolo.equals("F")){imagen=carF;}else
                                if(simbolo.equals("G")){imagen=carG;}
        return imagen;
    }
    
    public void cargarImagenes(){
        
        try {
            muro= ImageIO.read(new File("imagenes/ladrillo.jpg"));
            carA= ImageIO.read(new File(imagenTipoVehiculo("A")));
            carB= ImageIO.read(new File(imagenTipoVehiculo("B")));
            carC= ImageIO.read(new File(imagenTipoVehiculo("C")));
            carD= ImageIO.read(new File(imagenTipoVehiculo("D")));
            carE= ImageIO.read(new File(imagenTipoVehiculo("E")));
            carF= ImageIO.read(new File(imagenTipoVehiculo("F")));
            carG= ImageIO.read(new File(imagenTipoVehiculo("G")));
            
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null,"Error al cargar las imagenes del mapa","Error",JOptionPane.ERROR_MESSAGE);
        }
    }

//    @Override
//    public void run() {
//        boolean mover=false;
//        int pfx = 0,pfy = 0,pfcx = 0,pfcy = 0,px = 0,py = 0,id=0,p=0;
//        String carro = null,direccion=null;
//        int casillas=0;
//        while(true){
//
//            if(p<resultado.size()){
//            if(!mover){
//                    parametros=resultado.get(p);
//                    carro=parametros[0];
//                    direccion=parametros[1];
//                    casillas=Integer.parseInt(parametros[2]);
//                    id=vehiculos.indexOf(carro);
//                    px=posiciones[id][0];
//                    py=posiciones[id][1];
//                        
//                    
//                    if(direccion.equals("Arriba")){
//                        pfy=py-casillas;
//                        pfcy=(alto-3)-(7-pfy)*altoFila;
//                    }
//                    if(direccion.equals("Abajo")){
//                        pfy=py+casillas;
//                        pfcy=(alto-3)-(7-pfy)*altoFila;
//                    }
//                    if(direccion.equals("Izquierda")){
//                        pfx=px-casillas;
//                        pfcx=(ancho-3)-(7-pfx)*anchoFila;
//                    }
//                    if(direccion.equals("Derecha")){
//                        pfx=px+casillas;
//                        pfcx=(ancho-3)-(7-pfx)*anchoFila;
//                    }
//                mover=true;
//                }
//            if(mover) {
//                if(direccion.equals("Arriba")){
//                    if(posicionesCanvas[id][1]>pfcy)posicionesCanvas[id][1]--;
//                    if(posicionesCanvas[id][1]==pfcy){
//                        mover=false;
//                        p++;
//                        posiciones[id][1]=pfy;
//                    }
//                }
//                if(direccion.equals("Abajo")){
//                    if(posicionesCanvas[id][1]<pfcy)posicionesCanvas[id][1]++;
//                    if(posicionesCanvas[id][1]==pfcy){
//                        mover=false;                        
//                        p++;
//                        posiciones[id][1]=pfy;
//                    }
//                }
//                if(direccion.equals("Izquierda")){
//                    if(posicionesCanvas[id][0]>pfcx)posicionesCanvas[id][0]--;
//                    if(posicionesCanvas[id][0]==pfcx){
//                        mover=false;
//                        p++;
//                        posiciones[id][0]=pfx;
//                    }
//                }
//                if(direccion.equals("Derecha")){
//                    if(posicionesCanvas[id][0]<pfcx)posicionesCanvas[id][0]++;
//                    if(posicionesCanvas[id][0]==pfcx){
//                        mover=false;
//                        p++;
//                        posiciones[id][0]=pfx;
//                    }
//                }
//            }
//            
//        }
//            try {
//                  movimiento.sleep(8);
//                  repaint();
//                } catch (InterruptedException ex) {
//                    Logger.getLogger(ProyectoCanvas.class.getName()).log(Level.SEVERE, null, ex);
//                }
//    }
//    }
    @Override
    public void run() {
        
        int pfx,pfy,pfcx,pfcy;
        
        for (int p = 0; p < resultado.size(); p++) {
            
        parametros= resultado.get(p);
        for(int i=0; i<7; i++){
            
        
            if(parametros[0].equals(carros[i])){
                if(parametros[1].equals("Arriba")){
                    pfx=posiciones[i][0];
                    pfy=posiciones[i][1]-Integer.parseInt(parametros[2]);
                    pfcx=(ancho-3)-(7-pfx)*anchoFila;
                    pfcy=(alto-3)-(7-pfy)*altoFila;
                    while(posicionesCanvas[i][1]>=pfcy){
                        posicionesCanvas[i][1]--;
                        
                        try {
                            Thread.sleep(8);
                            repaint();
                        } catch (InterruptedException ex) {
                            Logger.getLogger(ProyectoCanvas.class.getName()).log(Level.SEVERE, null, ex);
                        }
    
                    }
                    posiciones[i][1]=pfy;
                }else
                if(parametros[1].equals("Abajo")){
                    pfx=posiciones[i][0];
                    pfy=posiciones[i][1]+Integer.parseInt(parametros[2]);
                    pfcx=(ancho-3)-(7-pfx)*anchoFila;
                    pfcy=(alto-3)-(7-pfy)*altoFila;
                    while(posicionesCanvas[i][1]<=pfcy){
                        posicionesCanvas[i][1]++;
                        
                        try {
                            Thread.sleep(8);
                            repaint();
                        } catch (InterruptedException ex) {
                            Logger.getLogger(ProyectoCanvas.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    posiciones[i][1]=pfy;
                }else
                if(parametros[1].equals("Izquierda")){
                    pfx=posiciones[i][0]-Integer.parseInt(parametros[2]);
                    pfy=posiciones[i][1];
                    pfcx=(ancho-3)-(7-pfx)*anchoFila;
                    pfcy=(alto-3)-(7-pfy)*altoFila;
                    while(posicionesCanvas[i][0]>=pfcx){
                        posicionesCanvas[i][0]--;
                        
                        try {
                            Thread.sleep(8);
                            repaint();
                        } catch (InterruptedException ex) {
                            Logger.getLogger(ProyectoCanvas.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    posiciones[i][0]=pfx;
                }else
                if(parametros[1].equals("Derecha")){
                    pfx=posiciones[i][0]+Integer.parseInt(parametros[2]);
                    pfy=posiciones[i][1];
                    pfcx=(ancho-3)-(7-pfx)*anchoFila;
                    pfcy=(alto-3)-(7-pfy)*altoFila;
                    while(posicionesCanvas[i][0]<=pfcx){
                        posicionesCanvas[i][0]++;
                        
                        
                        try {
                            Thread.sleep(8);
                            repaint();
                        } catch (InterruptedException ex) {
                            Logger.getLogger(ProyectoCanvas.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    posiciones[i][0]=pfx;
                }
            }
        }
    }
    }
}
